home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / AOCE / Development Tools / Sample Code / Digital Signatures / Digital Signature Demo / Source ƒ / DemoSignedObjectDialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-11  |  9.5 KB  |  347 lines  |  [TEXT/KAHL]

  1. /*
  2.  * DemoSignedObjectDialog.c
  3.  *    Copyright © 1992-93 Apple Computer Inc. All rights reserved.
  4.  * This sub-class to CDialog demonstrates how the Digital
  5.  * Signature Manager may be used to sign and verify individual
  6.  * data objects.
  7.  */
  8. #include "Demo.h"
  9. #include "DemoSignedObject.h"
  10. #include "DemoSignedObjectDialog.h"
  11. #include <CCheckBox.h>
  12. #include <CDataFile.h>
  13. #include <CDialog.h>
  14. #include <CDialogText.h>
  15. #include <CError.h>
  16. #include <CIconPane.h>
  17. #include <CRadioGroupPane.h>
  18. #include <Commands.h>
  19. #include <Exceptions.h>
  20. #include <Global.h>
  21. #include <TBUtilities.h>
  22.  
  23. #include <OCEErrors.h>
  24. extern CError                *gError;
  25. extern CursHandle            gWatchCursor;
  26. extern Boolean                gHasDigitalSignatureManager;
  27. void                        Message(
  28.         const StringPtr            textString
  29.     );
  30.  
  31. /*
  32.  * Imagine that you have written a payroll application and you
  33.  * want to allow your employees to change their authorizations
  34.  * or other information by electronic (AOCE) mail. You would
  35.  * distribute an application that presents a dialog with various
  36.  * checkboxes, edit text fields, and whatnot. The employee would
  37.  * fill in the requisite information and mail the data to the
  38.  * personnel database maintainers.
  39.  *
  40.  * Using the Digital Signature Manager, you can now sign
  41.  * individual fields of the document (in addition to the
  42.  * document itself). This lets you prevent unauthorized
  43.  * modifications to the information, as well as letting you
  44.  * have different fields signed by different individuals.
  45.  * For example, you could allow the employee to select
  46.  * pension distribution or emergency contacts, but require
  47.  * the employee's supervisor's "signature" to change the
  48.  * actual pay rate.
  49.  *
  50.  * This sample shows how the contents of a modal dialog can
  51.  * be signed and verified. It has several checkboxes, radio
  52.  * buttons, and an edit text field. After adjusting the fields
  53.  * "to suit the fashion and the time," the user can then
  54.  * command the following operations:
  55.  *
  56.  * Sign                    Compute a Digital Signature for
  57.  *                        the dialog's current contents.
  58.  * Verify                Check the current contents against
  59.  *                        the current signature.
  60.  * Show Signer            Show the signer information for the
  61.  *                        current signature.
  62.  * Save Signature        Write the current signature to a
  63.  *                        designated file.
  64.  * Read Signature        Read the designated file to obtain
  65.  *                        a new, current signature.
  66.  *
  67.  * This demo has been implemented as a Think Class Library
  68.  * Modal Dialog. Internally, it is a normal window and uses
  69.  * the normal window operations. In particular, it does
  70.  * use the standard event loop to handle events. This is
  71.  * essential as the Signer Manager status function calls
  72.  * the Think Class Library event loop, which crashes if
  73.  * there is a modal dialog in the window list.
  74.  */
  75.  
  76. /*
  77.  * The dialog content. Dialog items have commands
  78.  * that are (item number + kSignedDialogCmdBase).
  79.  * I.e., the OK button has (kSignedDialogCmdBase + dOKButton)
  80.  * Dialog item numbering must, of course, match the
  81.  * numbering in the dialog itself. Also, the way that
  82.  * TCL finds dialog items requires that the radio
  83.  * buttons be last in the list.
  84.  *
  85.  * Note that the dialog Icon item references the "valid
  86.  * signature" icon defined by the Digital Signature Mangager.
  87.  */
  88. enum {
  89.     dOKButton                    = 1,
  90.         dFirstButton            = dOKButton,
  91.     dSignButton,
  92.     dVerifyButton,
  93.     dSaveSignatureButton,
  94.     dReadSignatureButton,
  95.     dShowSignerButton,
  96.         dLastButton                = dShowSignerButton,
  97. /* Check boxes. Note: the order must agree with gCheckBoxMask[] */
  98.     dAwesomeCheckBox,
  99.         dFirstCheckBox            = dAwesomeCheckBox,
  100.     dEtherealCheckBox,
  101.     dExquisiteCheckBox,
  102.     dFabulousCheckBox,
  103.     dFantasticCheckBox,
  104.     dStupendousCheckBox,
  105.         dLastCheckBox            = dStupendousCheckBox,
  106.     dCommentaryText,
  107.     dStaticText14,
  108.     dStaticText15,
  109.     dStaticText16,
  110.     dStaticText17,
  111.     dStaticText18,
  112.     dRadioPaneDefinition,
  113. /* Radio buttons */
  114.     dFlauntRadioButton,
  115.         dFirstRadioButton        = dFlauntRadioButton,
  116.     dFloutRadioButton,
  117.         dLastRadioButton        = dFloutRadioButton,
  118.     dSignedIcon
  119. };
  120. #define CMD(what)        (kSignedDialogCmdBase + (what))
  121.  
  122. /*
  123.  * These are organized in the same order as the
  124.  * checkbox dialog items.
  125.  */
  126. static unsigned short gCheckBoxMask[] = {
  127.     kAwesomeMask,
  128.     kExquisiteMask,
  129.     kEtherealMask,
  130.     kFabulousMask,
  131.     kFantasticMask,
  132.     kStupendousMask
  133. };
  134. #define nCheckBoxes    (dLastCheckBox - dFirstCheckBox + 1)
  135.  
  136. #define    itsDialog    ((CDialog *) itsWindow)
  137.  
  138. void
  139. DemoSignedObjectDialog::IDemoSignedObjectDialog(
  140.         CDirectorOwner                *aSupervisor,
  141.         DemoSignedObject            *aSignedObject
  142.     )
  143. {
  144.         inherited::IDLOGDirector(DLOG_DemoSignedObject, aSupervisor);
  145.         itsSignatureValidFlag = FALSE;
  146.         itsSignedObject = aSignedObject;
  147.         AttachCommands();
  148.         SetDialogValues();
  149.         UpdateButtons();
  150. }
  151.  
  152. void
  153. DemoSignedObjectDialog::DoCommand(
  154.         long                        aCommand
  155.     )
  156. {
  157.         Boolean                    wasModal;
  158.         
  159.         /*
  160.          * Make the dialog temporarily non-modal
  161.          * so that the status window appears
  162.          * in front.
  163.          */
  164.         wasModal = itsDialog->IsModal();
  165.         itsDialog->SetModal(FALSE);
  166.         switch (aCommand) {
  167.         case CMD(dSignButton):
  168.             GetDialogValues();
  169.             itsSignatureValidFlag =
  170.                 itsSignedObject->SignThisObject();
  171.             UpdateButtons();
  172.             break;
  173.         case CMD(dVerifyButton):
  174.             GetDialogValues();
  175.             itsSignatureValidFlag =
  176.                 itsSignedObject->VerifyThisObject();
  177.             UpdateButtons();
  178.             break;
  179.         case CMD(dSaveSignatureButton):
  180.             itsSignedObject->SaveObjectSignature();
  181.             break;
  182.         case CMD(dReadSignatureButton):
  183.             itsSignedObject->ReadObjectSignature();
  184.             itsSignatureValidFlag = FALSE;
  185.             UpdateButtons();
  186.             break;
  187.         case CMD(dShowSignerButton):
  188.             /*
  189.              * The user chose "Show Signer." We'll get an error
  190.              * if we haven't used the signature to verify the
  191.              * dialog. In particular, if you sign the dialog
  192.              * and try to show signer, you'll get this error
  193.              * message. Note that UpdateButtons disables this
  194.              * button except after successful verification.
  195.              */
  196.             TRY {
  197.                 itsSignedObject->ShowSigner("\p");
  198.             }
  199.             CATCH {
  200.                 if (gLastError == kSIGOperationIncompatibleErr) {
  201.                     Message("\pShow signer is valid only after verification");
  202.                     NO_PROPAGATE;
  203.                 }
  204.             }
  205.             ENDTRY;
  206.             break;
  207.         case CMD(dOKButton):
  208.             aCommand = cmdOK;
  209.             goto doModalAction;
  210.         default:
  211.             itsSignatureValidFlag = FALSE;
  212.             UpdateButtons();
  213. doModalAction:
  214.             itsDialog->SetModal(wasModal);
  215.             inherited::DoCommand(aCommand);
  216.             break;
  217.         }
  218.         itsDialog->SetModal(wasModal);
  219. }
  220.  
  221. Boolean
  222. DemoSignedObjectDialog::EndDialog(
  223.         long                    withCommand,
  224.         Boolean                    fValidate
  225.     )
  226. {
  227.         Boolean                    result;
  228.         
  229.         result = inherited::EndDialog(withCommand, fValidate);
  230.         if (withCommand == cmdOK && result == TRUE)
  231.             GetDialogValues();
  232. }
  233.  
  234. void
  235. DemoSignedObjectDialog::GetDialogValues(void)
  236. {
  237.         register short                i;
  238.         unsigned short                checkBoxValue;
  239.         CCheckBox                    *aButton;
  240.         CRadioGroupPane                *aRadioGroup;
  241.         CDialogText                    *someEditText;
  242.         Str255                        someText;
  243.  
  244.         checkBoxValue = 0;
  245.         for (i = 0; i < nCheckBoxes; i++) {
  246.             aButton = (CCheckBox *) GetDialogItem(i + dFirstCheckBox);
  247.             if (aButton->IsChecked())
  248.                 checkBoxValue |= gCheckBoxMask[i];
  249.         }
  250.         itsSignedObject->SetCheckBoxValues(checkBoxValue);
  251.         aRadioGroup = (CRadioGroupPane *) GetDialogItem(dRadioPaneDefinition);
  252.         itsSignedObject->SetRadioButtonValue(
  253.             aRadioGroup->GetStationID() - dFirstRadioButton + 1
  254.         );
  255.         someEditText = (CDialogText *) GetDialogItem(dCommentaryText);
  256.         someEditText->GetTextString(someText);
  257.         itsSignedObject->SetCommentaryText(someText);
  258. }
  259.  
  260. void
  261. DemoSignedObjectDialog::SetDialogValues(void)
  262. {
  263.         register short                i;
  264.         unsigned short                checkBoxValue;
  265.         CCheckBox                    *aButton;
  266.         CRadioGroupPane                *aRadioGroup;
  267.         CEditText                    *someEditText;
  268.         Boolean                        isChecked;
  269.         Str255                        someText;
  270.                 
  271.         checkBoxValue = itsSignedObject->GetCheckBoxValues();
  272.         for (i = 0; i < nCheckBoxes; i++) {
  273.             aButton = (CCheckBox *) GetDialogItem(i + dFirstCheckBox);
  274.             isChecked = ((checkBoxValue & gCheckBoxMask[i]) != 0);
  275.             aButton->SetValue(isChecked);
  276.         }
  277.         aRadioGroup = (CRadioGroupPane *) GetDialogItem(dRadioPaneDefinition);
  278.         aRadioGroup->SetStationID(
  279.             itsSignedObject->GetRadioButtonValue() + dFirstRadioButton - 1
  280.         );
  281.         someEditText = (CEditText *) GetDialogItem(dCommentaryText);
  282.         itsSignedObject->GetCommentaryText(someText);
  283.         someEditText->SetTextPtr((Ptr) &someText[1], someText[0]);
  284. }
  285.  
  286. void
  287. DemoSignedObjectDialog::AttachCommands(void)
  288. {
  289.         register short            i;
  290.         
  291.         for (i = dFirstButton; i <= dLastButton; i++)
  292.             GetDialogItem(i)->SetClickCmd(CMD(i));
  293. }
  294.  
  295. void
  296. DemoSignedObjectDialog::UpdateButtons(void)
  297. {
  298.         CIconPane                    *anIconPane;
  299.  
  300.  
  301.         anIconPane = (CIconPane *) GetDialogItem(dSignedIcon);
  302.         /*
  303.          * It might be better to use different icons for
  304.          * "has signature" and "doesn't have signature",
  305.          * but CIconPane doesn't easily lend itself to
  306.          * having multiple icons and I don't really
  307.          * want to have two dialog items on top of
  308.          * each other.
  309.          */
  310.         if (itsSignatureValidFlag)
  311.             anIconPane->Show();
  312.         else {
  313.             anIconPane->Hide();
  314.         }
  315.         if (gHasDigitalSignatureManager == FALSE) {
  316.             GetDialogItem(dSignButton)->Deactivate();
  317.             GetDialogItem(dVerifyButton)->Deactivate();
  318.             GetDialogItem(dShowSignerButton)->Deactivate();
  319.         }
  320.         else {
  321.             if (itsSignedObject->HasSignature()) {
  322.                 GetDialogItem(dVerifyButton)->Activate();
  323.                 GetDialogItem(dSaveSignatureButton)->Activate();
  324.             }
  325.             else {
  326.                 GetDialogItem(dVerifyButton)->Deactivate();
  327.                 GetDialogItem(dSaveSignatureButton)->Deactivate();
  328.             }
  329.             if (itsSignedObject->GetContextType() == kSIGVerify
  330.               && itsSignedObject->HasSignature())
  331.                 GetDialogItem(dShowSignerButton)->Activate();
  332.             else {
  333.                 GetDialogItem(dShowSignerButton)->Deactivate();
  334.             }
  335.         }
  336. }
  337.  
  338. CButton *
  339. DemoSignedObjectDialog::GetDialogItem(
  340.         short                dialogID
  341.     )
  342. {
  343.         return ((CButton *) itsWindow->FindViewByID(dialogID));
  344. }
  345.  
  346.  
  347.